package cn.schoolwow.workflow.test.module.initial;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.database.parent.DatabaseType;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.query.resource.QueryResource;
import cn.schoolwow.util.domain.query.resource.QueryResourceResponse;
import cn.schoolwow.util.module.query.resource.domain.SingleQueryResourceHandler;
import cn.schoolwow.workflow.QuickWorkFlow;
import cn.schoolwow.workflow.QuickWorkFlowBuilder;
import cn.schoolwow.workflow.domain.deploy.WorkFlowDefinitionOption;
import cn.schoolwow.workflow.domain.deploy.WorkFlowDeployRequest;
import cn.schoolwow.workflow.test.domain.QuickWorkFlowTestOption;
import cn.schoolwow.workflow.test.module.initial.database.SetMySqlDataSourceFlow;
import cn.schoolwow.workflow.test.module.initial.database.SetPostgreDataSourceFlow;
import cn.schoolwow.workflow.test.module.initial.listener.TestWorkFlowInstanceListener;
import cn.schoolwow.workflow.test.module.initial.listener.TestWorkFlowTaskListener;
import com.zaxxer.hikari.HikariDataSource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class InitialQuickWorkFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        QuickWorkFlowTestOption quickWorkFlowTestOption = flowContext.checkInstanceData(QuickWorkFlowTestOption.class);

        setQuickWorkFlow(flowContext);
        if(!quickWorkFlowTestOption.loadWorkFlow){
            return;
        }
        deployWorkFlow(flowContext);
    }

    @Override
    public String name() {
        return "初始化工作流对象";
    }

    private void setQuickWorkFlow(FlowContext flowContext){
        DatabaseType databaseType = flowContext.checkInstanceData(DatabaseType.class);
        switch (databaseType){
            case Postgresql:{flowContext.executeFlowList(new SetPostgreDataSourceFlow());}break;
            case Mysql:{flowContext.executeFlowList(new SetMySqlDataSourceFlow());}break;
            default:{
                throw new IllegalArgumentException("暂不支持该数据库!数据库:"+databaseType.name());
            }
        }
        HikariDataSource hikariDataSource = flowContext.checkInstanceData(HikariDataSource.class);

        QuickWorkFlow quickWorkFlow = QuickWorkFlowBuilder
                .newInstance()
                .dataSource(hikariDataSource)
                .workFlowInstanceListener(new TestWorkFlowInstanceListener())
                .workFlowTaskListener(new TestWorkFlowTaskListener())
                .build();
        DAO dao = quickWorkFlow.getWorkFlow().getContextInstanceData(DAO.class);

        Collection<Entity> entities = dao.getEntityMap().values();
        for(Entity entity:entities){
            dao.truncate(entity.clazz);
        }

        flowContext.putContextInstanceData(dao, DAO.class);
        flowContext.putContextInstanceData(quickWorkFlow, QuickWorkFlow.class);
    }

    private void deployWorkFlow(FlowContext flowContext){
        QuickWorkFlowTestOption quickWorkFlowTestOption = flowContext.checkInstanceData(QuickWorkFlowTestOption.class);
        QuickWorkFlow quickWorkFlow = flowContext.checkInstanceData(QuickWorkFlow.class);

        List<String> deployNameList = new ArrayList<>();
        QueryResource queryResource = QueryResource.newQuery("工作流列表", "workflow")
                .fileNameEndWith(".json");
        if(null!=quickWorkFlowTestOption.filterDefinitionName){
            queryResource.fileNameEndWith(quickWorkFlowTestOption.filterDefinitionName+".json");
        }

        queryResource.singleQueryResourceHandler(new SingleQueryResourceHandler() {
                    @Override
                    public boolean handleQueryResourceResponse(QueryResourceResponse queryResourceResponse) {
                        String fileName = queryResourceResponse.getFileName();
                        String deployName = fileName.substring(0, fileName.indexOf("."));
                        deployNameList.add(deployName);
                        if(!quickWorkFlow.hasDeploy(deployName)){
                            WorkFlowDeployRequest workFlowDeployRequest = new WorkFlowDeployRequest();
                            workFlowDeployRequest.name = deployName;
                            workFlowDeployRequest.inputStream = queryResourceResponse.getAsInputStream();

                            WorkFlowDefinitionOption workFlowDefinitionOption = new WorkFlowDefinitionOption();
                            switch (deployName){
                                case "智能去重测试工作流审批":{
                                    workFlowDefinitionOption.intelligent = true;
                                }break;
                                case "分析工作报告审批":{
                                    workFlowDefinitionOption.allowAdd = true;
                                    workFlowDefinitionOption.allowRevoke = true;
                                }break;
                            }
                            workFlowDeployRequest.workFlowDefinitionOption = workFlowDefinitionOption;
                            quickWorkFlow.deployWorkFlow(workFlowDeployRequest);
                        }
                        return true;
                    }
                })
                .execute()
                .walkResource();
    }
}
